home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
os2
/
octa209s.zip
/
octave-2.09
/
libs
/
mkfifo
/
nmp_thread.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-08-22
|
4KB
|
154 lines
/*
** ****************************************************************************
** Thread for exchanging the data. This routine is started by the server in
** new thread for every nmaed pipe.
** (c) Klaus Gebhardt, 1997
** ****************************************************************************
*/
/*
** ****************************************************************************
** This is part of the server the mkfifo command connects to. This program
** creates a named pipe which is used for communication between the mkfifo
** routine and the server. The mkfifo sends the name of the named pipe,
** which should be created and then receives the return code.
** (c) Klaus Gebhardt, 1997
** ****************************************************************************
*/
/*
** ****************************************************************************
** This was written for the OS/2 port of Octave, but it is not part of Octave!
** You can use the code UNMODIFIED. If you think changes are necessary,
** please send me a mail (gebhardt@crunch.ikp.physik.th-darmstadt.de).
** Thanks,
** Klaus Gebhardt
** ****************************************************************************
*/
#include "nmp.h"
/*
** This function creates a named pipe and connects to it. The function
** returns 0 on success, -1 on error.
*/
static int create_npipe (const char *name, HPIPE *hpipe)
{
APIRET apiret;
apiret = DosCreateNPipe (name, hpipe, NP_ACCESS_DUPLEX,
NP_NOWAIT | NP_TYPE_BYTE | NP_READMODE_BYTE |
0xFF, 1024L, 1024L, -1);
if (apiret) return -1;
apiret = DosConnectNPipe (*hpipe);
if (apiret && (apiret != 233)) return -1;
apiret = DosSetNPHState (*hpipe, NP_WAIT);
if (apiret && (apiret != 233)) return -1;
return 0;
}
/*
** This routine disconnects from a named pipe and closes the named pipe.
** It returns 0 on success, -1 on error.
*/
static int disconnect_npipe (HPIPE hpipe)
{
DosDisConnectNPipe (hpipe);
DosClose (hpipe);
return 0;
}
/*
** This is the thread for moving the data from one end to the other. When
** a client closes its connection to a named pipe, the named pipe will be
** closed and recreated.
*/
void nmp_thread (void *ptr)
{
APIRET apiret;
HPIPE hpipe1, hpipe2;
ULONG count1r = 0, count2w = 0, count2r = 0, count1w = 0, tmp;
AVAILDATA available1, available2;
ULONG state1, state2;
_named_pipe_ *nmp;
char data1[1024], data2[1024];
int rc;
nmp = (_named_pipe_ *) ptr;
nmp->result = 0;
rc = create_npipe (nmp->name, &hpipe1); if (rc) nmp->result = -1;
rc = create_npipe (nmp->name, &hpipe2); if (rc) nmp->result = -1;
DosPostEventSem (_hev_);
while (nmp->tid != -1)
{
DosPeekNPipe (hpipe1, &rc, sizeof(rc), &tmp, &available1, &state1);
DosPeekNPipe (hpipe2, &rc, sizeof(rc), &tmp, &available2, &state2);
if ((count1r > count2w) || (available1.cbpipe > 0))
{
if (count1r <= count2w)
{
DosRead (hpipe1, data1, sizeof(data1), &count1r);
count2w = 0;
}
if (count1r > count2w)
{
DosWrite (hpipe2, data1+count2w, count1r-count2w, &tmp);
count2w += tmp;
}
}
else if (state1 == NP_STATE_CLOSING)
{
disconnect_npipe (hpipe1);
rc = create_npipe (nmp->name, &hpipe1);
if (rc) goto error;
}
if ((count2r > count1w) || (available2.cbpipe > 0))
{
if (count2r <= count1w)
{
DosRead (hpipe2, data2, sizeof(data2), &count2r);
count1w = 0;
}
if (count2r > count1w)
{
DosWrite (hpipe1, data2+count1w, count2r-count1w, &tmp);
count1w += tmp;
}
}
else if (state2 == NP_STATE_CLOSING)
{
disconnect_npipe (hpipe2);
rc = create_npipe (nmp->name, &hpipe2);
if (rc) goto error;
}
}
disconnect_npipe (hpipe1);
disconnect_npipe (hpipe2);
_endthread ();
return;
error:
nmp->result = -1;
disconnect_npipe (hpipe1);
disconnect_npipe (hpipe2);
_endthread ();
return;
}